<template>
  <div class="hotel-manage">
    <!-- 搜索 -->
    <div class="form admin-common-bg">
      <el-form :inline="true" :model="formData" style="text-align: left">
        <el-form-item label="酒店名称">
          <el-input
            v-model="formData.name"
            placeholder="请输入酒店名称"
            size="mini"
            :clearable="true"
            style="width: 200px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="mini" @click="search"
            ><i class="el-icon-search"></i>查询</el-button
          >
          <el-button size="mini" @click="reset"
            ><i class="el-icon-refresh"></i>重置</el-button
          >
        </el-form-item>
      </el-form>
    </div>
    <!-- 数据列表 -->
    <div class="content admin-common-bg">
      <div class="operate">
        <el-button
          type="primary"
          size="mini"
          icon="el-icon-plus"
          plain
          @click="dialogVisible = true"
          >新增</el-button
        >
        <el-button
          type="danger"
          size="mini"
          icon="el-icon-delete"
          plain
          v-show="multipleSelection.length !== 0"
          @click="batchDelete"
          >批量删除</el-button
        >
      </div>
      <div style="min-height: 294px">
        <el-table
          :data="dataList"
          :header-cell-style="{ background: '#f5f5f5' }"
          v-loading="tableLoading"
          @selection-change="handleSelectionChange"
          style="width: 100%"
        >
          <el-table-column type="selection" width="46" align="center">
          </el-table-column>
          <el-table-column
            type="index"
            width="49"
            :index="indexConfig"
            label="序号"
            align="center"
          ></el-table-column>
          <el-table-column
            prop="name"
            label="酒店名称"
            width="140"
            align="center"
            :show-overflow-tooltip="true"
          >
          </el-table-column>
          <el-table-column
            prop="address"
            label="地址"
            width="140"
            align="center"
            :show-overflow-tooltip="true"
          >
          </el-table-column>
          <el-table-column
            prop="introduce"
            label="简介"
            width="160"
            align="center"
            :show-overflow-tooltip="true"
          >
          </el-table-column>
          <el-table-column label="状态" width="80" align="center">
            <template slot-scope="scope">
              <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">{{
                scope.row.status === 1 ? "启用" : "禁用"
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="创建时间" width="160" align="center">
            <template slot-scope="scope">
              {{ formatDate(scope.row.createTime) }}
            </template>
          </el-table-column>
          <el-table-column label="修改时间" width="160" align="center">
            <template slot-scope="scope">
              {{ formatDate(scope.row.updateTime) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <template slot-scope="scope">
              <el-button
                type="warning"
                size="mini"
                @click="updateStatus(scope.row)"
                >{{ scope.row.status === 1 ? "禁用" : "启用" }}</el-button
              >
              <el-button
                type="info"
                size="mini"
                @click="$router.push(`/admin/hotel/specs/${scope.row.id}`)"
                >房型</el-button
              >
              <el-button type="primary" size="mini" @click="edit(scope.row)"
                >修改</el-button
              >
              <el-button type="danger" size="mini" @click="del(scope.row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页 -->
        <el-pagination
          v-show="dataList.length > 0"
          background
          layout="prev, pager, next"
          :total="total"
          :current-page="currentPage"
          :page-size="pageSize"
          @current-change="handleCurrentChange"
          :page-count="7"
          style="text-align: right; margin-top: 24px"
        >
        </el-pagination>
      </div>
    </div>
    <!-- 添加 -->
    <el-dialog
      title="添加酒店"
      :visible.sync="dialogVisible"
      width="40%"
      @close="handleClose"
      :close-on-click-modal="false"
    >
      <el-form
        :model="insertData"
        label-width="90px"
        :rules="rules"
        ref="insertForm"
      >
        <el-form-item label="酒店名" style="width: 84%" prop="name">
          <el-input
            v-model="insertData.name"
            placeholder="请输入酒店名"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="地址" style="width: 84%" prop="addressText">
          <el-cascader
            size="large"
            :options="regionData"
            v-model="selectedOptions"
            @change="handleChange"
            style="width: 100%"
            autocomplete="off"
          ></el-cascader>
        </el-form-item>
        <el-form-item
          label="详细地址"
          style="width: 84%"
          prop="addressDetailText"
        >
          <el-input
            v-model="insertData.addressDetailText"
            placeholder="请输入详细地址"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="简介" style="width: 84%" prop="introduce">
          <el-input
            v-model="insertData.introduce"
            placeholder="简介"
            type="textarea"
            :row="4"
            :clearable="true"
            autocomplete="off"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="图片" style="width: 84%" prop="cover">
          <div class="upload-avatar">
            <div class="avatar">
              <img :src="insertData.cover || defaultCover" alt="" />
              <el-upload
                action="zhanweifu"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="changeFile"
              >
                <span v-loading="uploadLoading"></span>
              </el-upload>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="add" :loading="insertLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
    <!-- 修改 -->
    <el-dialog
      title="修改酒店信息"
      :visible.sync="updateDialogVisible"
      width="40%"
      @close="handleCloseUpdate"
      :close-on-click-modal="false"
    >
      <el-form
        :model="updateData"
        label-width="90px"
        :rules="rules"
        ref="updateForm"
      >
        <el-form-item label="酒店名" style="width: 84%" prop="name">
          <el-input
            v-model="updateData.name"
            placeholder="请输入酒店名"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="地址" style="width: 84%" prop="addressText">
          <el-cascader
            size="large"
            :options="pcaTextArr"
            v-model="selectedOptions"
            style="width: 100%"
            autocomplete="off"
          ></el-cascader>
        </el-form-item>
        <el-form-item
          label="详细地址"
          style="width: 84%"
          prop="addressDetailText"
        >
          <el-input
            v-model="updateData.addressDetailText"
            placeholder="请输入详细地址"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="简介" style="width: 84%" prop="introduce">
          <el-input
            v-model="updateData.introduce"
            placeholder="简介"
            type="textarea"
            :row="4"
            :clearable="true"
            autocomplete="off"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="图片" style="width: 84%" prop="cover">
          <div class="upload-avatar">
            <div class="avatar">
              <img :src="updateData.cover || defaultCover" alt="" />
              <el-upload
                action="zhanweifu"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="changeFile"
              >
                <span v-loading="uploadLoading"></span>
              </el-upload>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="updateDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="update" :loading="updateLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>
 
 <script>
import defaultCover from "@/assets/defaultCover.png";
import { regionData, pcaTextArr, codeToText } from "element-china-area-data";
import { uploadFile } from "@/api/common";
import { MessageBox } from "element-ui";
import {
  addHotel,
  deleteByIds,
  getHotelList,
  updateHotel,
  updateStatus,
} from "@/api/admin/hotel";
export default {
  name: "HotelManage",
  data() {
    return {
      defaultCover,
      formData: {
        name: "",
      },
      page: 1,
      pageSize: 10,
      total: 0,
      currentPage: 1,
      dataList: [],
      insertData: {
        name: "",
        address: "",
        addressText: "",
        addressDetailText: "",
        introduce: "",
        cover: "",
      },
      rules: {
        name: [{ required: true, message: "请输入酒店名称", trigger: "blur" }],
        addressText: [
          { required: true, message: "请选择地址", trigger: "blur" },
        ],
        addressDetailText: [
          { required: true, message: "请输入详细地址", trigger: "blur" },
        ],
        introduce: [
          { required: true, message: "请输入酒店简介", trigger: "blur" },
        ],
        cover: [{ required: true, message: "请上传图片", trigger: "blur" }],
      },
      // 地区三级联动下拉框数据
      regionData,
      pcaTextArr,
      selectedOptions: [],
      updateData: {},
      dialogVisible: false,
      updateDialogVisible: false,
      tableLoading: false,
      insertLoading: false,
      updateLoading: false,
      uploadLoading: false,
      multipleSelection: [],
    };
  },
  created() {
    this.getTotelList();
  },
  methods: {
    // 搜索
    search() {
      if (this.formData.name === "") {
        this.$message.warning("请输入酒店名称");
        return;
      }
      this.page = 1;
      this.getTotelList();
    },
    // 重置
    reset() {
      this.page = 1;
      this.currentPage = 1;
      this.formData.name = "";
      this.getTotelList();
    },
    // 获取酒店列表
    async getTotelList() {
      try {
        this.tableLoading = true;
        const res = await getHotelList({
          page: this.page,
          pageSize: this.pageSize,
          ...this.formData,
        });
        this.dataList = res.data.records;
        this.total = res.data.total;
      } catch {
        this.$message.error("获取酒店列表失败");
      } finally {
        this.tableLoading = false;
      }
    },
    // 新增
    add() {
      this.$refs.insertForm.validate(async (v) => {
        if (v) {
          // 处理数据
          this.insertData.address =
            this.insertData.addressText + this.insertData.addressDetailText;
          try {
            this.insertLoading = true;
            const res = await addHotel(this.insertData);
            this.dialogVisible = false;
            this.getTotelList();
          } catch {
            this.$message.error("添加失败");
          } finally {
            this.insertLoading = false;
          }
        }
      });
    },
    // 删除
    async del(row) {
      MessageBox.confirm(
        "确定删除所选数据吗？这将删除该酒店的所有信息",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).then(async () => {
        const res = await deleteByIds([row.id]);
        await this.getTotelList();
      });
    },
    // 批量删除
    async batchDelete() {
      const ids = [];
      this.multipleSelection.forEach((item) => {
        ids.push(item.id);
      });
      MessageBox.confirm(
        "确定删除所选数据吗？这将删除该酒店的所有信息",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).then(async () => {
        const res = await deleteByIds(ids);
        await this.getTotelList();
      });
    },
    // 编辑信息
    edit(row) {
      this.updateDialogVisible = true;
      const split = row.address.split(" ");
      const addressArr = split.slice(0, split.length - 1);
      const addressDetailText = split.slice(split.length - 1);
      row.addressText = addressArr.join(" ");
      row.addressDetailText = addressDetailText[0];
      this.selectedOptions = addressArr;
      this.updateData = { ...row };
    },
    // 修改信息
    async update() {
      this.$refs.updateForm.validate(async (v) => {
        if (v) {
          // 处理数据
          this.updateData.address =
            this.selectedOptions.join(" ") +
            " " +
            this.updateData.addressDetailText;
          try {
            this.updateLoading = true;
            const res = await updateHotel(this.updateData);
            this.updateDialogVisible = false;
            this.getTotelList();
          } finally {
            this.updateLoading = false;
          }
        }
      });
    },
    // 修改状态
    async updateStatus(row) {
      const status = row.status === 1 ? 2 : 1;
      try {
        const res = await updateStatus({ id: row.id, status });
        this.getTotelList();
      } catch {
        this.$message.error("修改状态失败");
      }
    },

    // 配置表格索引
    indexConfig(index) {
      return (this.currentPage - 1) * this.pageSize + index + 1;
    },
    // 时间格式判断
    padZero(num) {
      return num < 10 ? "0" + num : num;
    },
    // 时间格式化
    formatDate(timeArray) {
      if (!timeArray) return "暂无时间";
      let year = timeArray[0];
      let month = this.padZero(timeArray[1]);
      let day = this.padZero(timeArray[2]);
      let hour = this.padZero(timeArray[3]);
      let minute = this.padZero(timeArray[4]);
      let second = this.padZero(timeArray[5]) || "00";
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    // 当选项发生变化触发
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 分页
    handleCurrentChange(page) {
      this.page = page;
      this.currentPage = page;
      this.getTotelList();
    },
    // 选择文件，上传图片
    async changeFile(file) {
      // 判断格式是否正确
      const bool = this.verifyFormat(file);
      if (!bool) {
        return;
      }
      // 上传到服务器
      this.uploadLoading = true;
      try {
        let formData = new FormData();
        // 拿到存在file中的文件存放到formData中
        formData.append("file", file.raw);
        const res = await uploadFile(formData);
        this.insertData.cover = res.data;
        this.updateData.cover = res.data;
      } finally {
        this.uploadLoading = false;
      }
    },
    // 上传图片前校验格式
    verifyFormat(file) {
      const isJPG =
        file.raw.type === "image/jpeg" || file.raw.type === "image/png";
      const isLt10M = file.raw.size / 1024 / 1024 < 10;
      if (!isJPG) {
        this.$message.error("上传图片只能是 jpg/jpeg/png 格式!");
        return false;
      }
      if (!isLt10M) {
        this.$message.error("上传图片大小不能超过 10MB!");
        return false;
      }
      return isJPG && isLt10M;
    },
    // 关闭弹窗
    handleClose() {
      this.insertLoading = false;
      this.selectedOptions = [];
      this.$refs.insertForm.resetFields();
    },
    // 关闭修改弹窗
    handleCloseUpdate() {
      this.updateLoading = false;
      this.selectedOptions = [];
      this.$refs.updateForm.resetFields();
    },
    // 地区下拉框选择
    handleChange() {
      var loc = "";
      for (let i = 0; i < this.selectedOptions.length; i++) {
        loc += codeToText[this.selectedOptions[i]] + " ";
      }
      this.insertData.addressText = loc;
    },
  },
};
</script>
 
<style lang="less" scoped>
.hotel-manage {
  width: 100%;
  height: 100%;
  margin-bottom: 16px;
  .form {
    padding-left: 20px;
    height: 40px;
    i {
      margin-right: 4px;
    }
  }
  .content {
    width: 100%;
    margin-top: 14px;
    padding-bottom: 16px;
    .operate {
      text-align: left;
      padding: 8px 10px;
    }
  }
  .upload-avatar {
    position: relative;
    width: 140px;
    height: 140px;
    .avatar {
      width: 100%;
      height: 100%;
      position: relative;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
      span {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 134px;
        height: 134px;
        transform: translate(-50%, -50%);
        &::before {
          content: "上传图片";
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 134px;
          height: 134px;
          background-color: rgba(0, 0, 0, 0.06);
          text-align: center;
          line-height: 134px;
          cursor: pointer;
          opacity: 0;
          visibility: hidden;
          z-index: 1;
          color: black;
        }
        &:hover::before {
          opacity: 1;
          visibility: visible;
        }
      }
    }
  }
}
</style>